package com.nbjtjc.safe.service.sys;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.nbjtjc.safe.bean.Constant;
import com.nbjtjc.safe.bean.Page;
import com.nbjtjc.safe.bean.Result;
import com.nbjtjc.safe.mapper.sys.SysDeptMapper;
import com.nbjtjc.safe.mapper.sys.SysFileMapper;
import com.nbjtjc.safe.model.sys.SysDept;
import com.nbjtjc.safe.model.sys.SysFile;
import com.nbjtjc.safe.model.sys.SysUser;
import com.nbjtjc.safe.util.MyShiroUtils;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysDeptService {

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private SysFileMapper sysFileMapper;
    @Value("${aliyun.oss.domain}")
    private String domain;
    public Result find(SysDept sysDept, Page page) {
        Result result = new Result();
        PageHelper.startPage(page.getPageCurrent(), page.getPageSize());
        List<SysDept> sysDepts = sysDeptMapper.search(sysDept, page);
        if (CollectionUtil.isEmpty(sysDepts)) {
            result.setData(new ArrayList<>());
        } else {
            result.setData(sysDepts);
        }
        return result;
    }

    public Result mvUp(SysDept sysDept) {
        Result result = new Result();
        List<SysDept> minDepts = sysDeptMapper.getUpDeptNum(sysDept.getParentId(), sysDept.getNum()
                , sysDept.getType());
        if (CollectionUtil.isEmpty(minDepts)) {
            return result;
        }
        SysDept minDept = minDepts.get(0);
        int temp = sysDept.getNum();
        sysDept.setNum(minDept.getNum());
        minDept.setNum(temp);
        sysDeptMapper.updateByPrimaryKeySelective(sysDept);
        sysDeptMapper.updateByPrimaryKeySelective(minDept);
        return result;
    }

    public Result mvDown(SysDept sysDept) {
        Result result = new Result();
        List<SysDept> maxDepts = sysDeptMapper.getDownDeptNum(sysDept.getParentId()
                , sysDept.getNum(), sysDept.getType());
        if (CollectionUtil.isEmpty(maxDepts)) {
            return result;
        }
        SysDept maxDept=maxDepts.get(0);
        int temp = sysDept.getNum();
        sysDept.setNum(maxDept.getNum());
        maxDept.setNum(temp);
        sysDeptMapper.updateByPrimaryKeySelective(sysDept);
        sysDeptMapper.updateByPrimaryKeySelective(maxDept);
        return result;
    }

    /**
     * 获取一个人当前所在部门的所有机构部门的关系
     *
     * @return
     */
    public Result getOrganiztionDept() {
        Result result = new Result();
        Subject subject = SecurityUtils.getSubject();
        SysUser sysUser = (SysUser) subject.getSession().getAttribute("user");
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(sysUser.getDeptId().intValue());
        List<SysDept> sysDepts=getCompanyDepts(sysDept,false,new ArrayList<>());
        result.setData(sysDepts);
        return result;
    }

    /**
     * 获取当前登入人员所在公司往下的所有公司部门的id
     * @return
     */
    public List<Integer> getSubDeptAndCompanyIds(int deptId){
        List<Integer> sysDeptIds=new ArrayList<>();
        SysDept sysDept=sysDeptMapper.selectByPrimaryKey(deptId);
        List<SysDept> sysDepts=new ArrayList<>();
        List<SysDept> tempDepts=getCompanyDepts(sysDept,false,sysDepts);
        if(CollectionUtil.isEmpty(tempDepts)){
            return sysDeptIds;
        }
         sysDeptIds=sysDepts.parallelStream()
                .map(SysDept::getId).collect(Collectors.toList());
        if(CollectionUtil.isEmpty(sysDeptIds)){
            return  new ArrayList<>();
        }
        sysDeptIds.add(MyShiroUtils.getCompanyId());
        return sysDeptIds;
    }
    /**
     * 获取母公司的人员部门的
     * @return
     */
    public Result getFartherCompanyDept(){
        Result result = new Result();
        int fartherCompanyId=getParentCompanyId(MyShiroUtils.getCompanyId());
        SysDept sysDept=null;
        if(fartherCompanyId==0){
            sysDept=sysDeptMapper.selectByPrimaryKey(MyShiroUtils.getCompanyId());
        }else{
            sysDept=sysDeptMapper.selectByPrimaryKey(fartherCompanyId);
        }
        result.setData(getCompanyDepts(sysDept,true,new ArrayList<>()));
        return result;
    }
    /**
     * 传入某个sysDept，如果是部门就获取该部门所在公司，并返回这个公司的部门结构
     * @param sysDept
     * @param onlyDept  只获取部门，不获取公司
     * @return
     */
    public List<SysDept> getCompanyDepts(SysDept sysDept, boolean onlyDept, List<SysDept> temp){
        List<SysDept> sysDepts=new ArrayList<>();
        SysDept topDept = null;
        if (ObjectUtil.isNull(sysDept)) {
            return sysDepts;
        }
        if (sysDept.getType().equals(Constant.SysDeptType.COMPANY.getValue())) {
            topDept = sysDept;
            getSubDept(topDept,onlyDept,temp);
        } else {
//            int topDeptId = getTopDeptId(sysDept.getParentId());
            topDept = sysDeptMapper.selectByPrimaryKey(sysDept.getParentId());
            getSubDept(topDept,onlyDept,temp);
        }
        sysDepts.add(topDept);
        return sysDepts;
    }

    public List<SysDept> getLowerCompanyDepts(){
        List<SysDept> orgDepts=new ArrayList<>();
        SysDept company=sysDeptMapper.selectByPrimaryKey(MyShiroUtils.getCompanyId());
        orgDepts.add(company);
        //TODO
        setCompanyLogo(company);
        List<SysDept> sysDepts=sysDeptMapper.findByParentIdNoUser(MyShiroUtils.getCompanyId());
        sysDepts.forEach(sysDept -> {
            setCompanyLogo(sysDept);
        });
        if(CollectionUtil.isNotEmpty(sysDepts)){
            company.setSubDept(sysDepts);
            Map<Integer,SysDept> deptMap=sysDepts.stream().collect(Collectors.toMap(SysDept::getId,dept->dept));
            getLower(deptMap);
        }
        return orgDepts;
    }


    private void getLower(Map<Integer,SysDept> deptMap){
        List<Integer> deptIds=new ArrayList<>(deptMap.keySet());
        List<SysDept> lowerDepts=sysDeptMapper.getLowerDepts(deptIds);
        if(CollectionUtil.isNotEmpty(lowerDepts)){
            lowerDepts.forEach(lowerDept->{
                setCompanyLogo(lowerDept);
                deptMap.get(lowerDept.getParentId()).getSubDept().add(lowerDept);
            });
            Map<Integer,SysDept> loweDeptMap=lowerDepts.stream().collect(Collectors.toMap(
                    SysDept::getId,sysDept -> sysDept
            ));
            getLower(loweDeptMap);
        }
    }

    /**
     * 设置公司的logo的路径
     * @param dept
     */
    private void setCompanyLogo(SysDept dept){
        try {
            if(dept.getType().equals(Constant.SysDeptType.DEPT.getValue())){
                return;
            }
            if(ObjectUtil.isNull(dept.getLogoFileId())){
                return;
            }
            SysFile sysFile=sysFileMapper.selectByPrimaryKey(dept.getLogoFileId());
            if(ObjectUtil.isNull(sysFile)||ObjectUtil.isNull(sysFile.getPath())){
                return;
            }
            dept.setLogoPath(domain+"/"+sysFile.getPath());
        } catch (Exception e) {
            e.printStackTrace();
        }
       
    }
    /**
     * 获取所有部门的树结构
     * @return
     */
    public List<SysDept> getAllConstruct(){
        List<SysDept> sysDepts = new ArrayList<>();
        SysDept sysDept = new SysDept();
        sysDept.setParentId(0);
        List<SysDept> topDepts = sysDeptMapper.search(sysDept, new Page());
        List<SysDept> allDepts=sysDeptMapper.selectAll();
        Map<Integer,List<SysDept>> parentIdMap=new HashMap<>();
        allDepts.forEach(dept->{
            if(parentIdMap.containsKey(dept.getParentId())){
                parentIdMap.get(dept.getParentId()).add(dept);
            }else{
                List<SysDept> sysDeptList=new ArrayList<>();
                sysDeptList.add(dept);
                parentIdMap.put(dept.getParentId(),sysDeptList);
            }
        });
        if(CollectionUtil.isNotEmpty(topDepts)){
            compareDept(topDepts,parentIdMap);
        }else{
            return sysDepts;
        }
        return topDepts;
    }

    private void compareDept(List<SysDept> sysDepts,Map<Integer,List<SysDept>> parentIdMap){
        if(CollectionUtil.isNotEmpty(sysDepts)){
            Comparator<SysDept> comparator=new Comparator<SysDept>() {
                @Override
                public int compare(SysDept o1, SysDept o2) {
                    if(o1.getType()<=o2.getType()){
                        return -1;
                    }else{
                        return 1;
                    }
                }
            };
            sysDepts.forEach(dept->{
                if(parentIdMap.containsKey(dept.getId())){
                    parentIdMap.get(dept.getId()).sort(comparator);
                    dept.setSubDept(parentIdMap.get(dept.getId()));
                    compareDept(parentIdMap.get(dept.getId()),parentIdMap);
                }
            });
        }
    }

    public void getSubDept(SysDept sysDept,boolean onlyDept,List<SysDept> temp) {
        List<SysDept> sysDepts;
        if(onlyDept){
            sysDepts= sysDeptMapper.findOnlyDeptByParentId(sysDept.getId(),
                    Constant.SysDeptType.DEPT.getValue());
        }else{
            sysDepts= sysDeptMapper.findByParentId(sysDept.getId());
        }
        if (CollectionUtil.isNotEmpty(sysDepts)) {
            temp.addAll(sysDepts);
            sysDept.setSubDept(sysDepts);
            sysDepts.forEach(dept -> {
                getSubDept(dept,onlyDept,temp);
            });
        }
    }

//    private void getSubDept(List<SysDept> parentDept) {
//        parentDept.forEach(sysDept -> {
//            List<SysDept> deptList = sysDeptMapper.findByParentId(sysDept.getId());
//            if (CollectionUtil.isNotEmpty(deptList) && deptList.size() > 0) {
//                getSubDept(deptList);
//                sysDept.setSubDept(deptList);
//            }
//        });
//    }

    private Integer getTopDeptId(int deptId) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        if (ObjectUtil.isNull(sysDept)) {
            return deptId;
        }
        if (sysDept.getParentId().equals(0)) {
            return deptId;
        }
        return getTopDeptId(sysDept.getParentId());
    }

    /**
     * 获得当前所在部门的上级母公司的id
     *
     * @param deptId 当前人员所在公司id
     * @return
     */
    public Integer getFatherCompanyId(int deptId) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(deptId);
        if (ObjectUtil.isNull(sysDept)) {
            return 0;
        }
        if (sysDept.getType().equals(1)) {//表示公司，0表示部门
            return sysDept.getId();
        } else {
            return getFatherCompanyId(sysDept.getParentId());
        }
    }

    public String getCompanyName() {
        SysDept sys=sysDeptMapper.selectByPrimaryKey(MyShiroUtils.getCompanyId());
        if (ObjectUtil.isNull(sys)) {
            return "";
        }
        return sys.getName();
    }
    /**
     * 返回当前公司的母公司的id
     *
     * @param companyId 当前人员所在公司id
     * @return
     */
    public Integer getParentCompanyId(int companyId) {
        SysDept sysDept = sysDeptMapper.selectByPrimaryKey(companyId);
        return sysDept.getParentId();
    }
    
    //返回本级和所有上级公司ID
    public List<Integer> getAllParentCompanyId(SysDept sysDept,List<Integer> sysDeptIds ) {

    	if(ObjectUtil.isNotNull(sysDept.getType())&&sysDept.getType()==1){
        	sysDeptIds.add(sysDept.getId());
    	}

    	if(ObjectUtil.isNull(sysDept.getParentId())||sysDept.getParentId()==0){
    		return sysDeptIds;
    	}
    	
    	SysDept sysDeptParent = sysDeptMapper.selectByPrimaryKey(sysDept.getParentId());
        if(ObjectUtil.isNotNull(sysDeptParent)){
        	sysDeptIds = getAllParentCompanyId(sysDeptParent,sysDeptIds);
        }
        return sysDeptIds;
    }
    
    
    //返回所有下级公司ID(不包括本级)
    public List<Integer> getAllSubCompanyId(Integer sysDeptId,List<Integer> sysDeptIds ) {

//    	if(ObjectUtil.isNotNull(sysDept.getType())&&sysDept.getType()==1){
//        	sysDeptIds.add(sysDept.getId());
//    	}else{
//    		return sysDeptIds;
//    	}

    	List<Integer> sysDeptIdsTemp = sysDeptMapper.getSubCompanyId(sysDeptId
                ,Constant.SysDeptType.COMPANY.getValue());
    	
    	if(CollectionUtil.isEmpty(sysDeptIdsTemp)){
    		return sysDeptIds;
    	}else{
    		sysDeptIds.addAll(sysDeptIdsTemp);
    		for(Integer i: sysDeptIdsTemp){
    			sysDeptIds = getAllSubCompanyId(i,sysDeptIds);
    		}
    		return sysDeptIds;
    	}
    	
//    	SysDept sysDeptParent = sysDeptMapper.selectByPrimaryKey(sysDept.getParentId());
//        if(ObjectUtil.isNotNull(sysDeptParent)){
//        	sysDeptIds = getAllParentCompanyId(sysDeptParent,sysDeptIds);
//        }
//        return sysDeptIds;
    }
    

}
